﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WFNetLib;
using System.IO.Ports;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using WFNetLib.GSMModem;
using WFNetLib.Forms;
using WFNetLib.Net;
using System.IO;
using System.IO.Compression;
using System.Net;

namespace SignIn
{
    public class ReaderThread
    {
        public SerialPort Com;
        public Thread ReaderThreadIns=null;
        public static event strEventHandler AddLogEvent;//事件声明
        public static event intEventHandler FinishEvent;//事件声明
#if DEBUG
        CommunicationDebugForm CommunicationDebugForm;
#endif


        GsmModem gsmModem;
        public string PortName;
        public int ComIndex;
        void OnAddLog(string strLog)
        {
            if (AddLogEvent != null)
            {  
                AddLogEvent(this,new strEventArgs(strLog));
            }
        }
        void OnFinishEvent(int n)
        {
            if (FinishEvent != null)
            {
                FinishEvent(this, new intEventArgs(n));
            }
        }     
        public ReaderThread(SerialPort _Com,int index)
        {
            Com = _Com;
            
#if DEBUG
            CommunicationDebugForm = new CommunicationDebugForm();
            //CommunicationDebugForm.IsClose = true;
            CommunicationDebugForm.Show();
            //CommunicationDebugForm.Hide();
            CommunicationDebugForm.Text = Com.PortName + "数据检测";
            gsmModem = new GsmModem(Com,CommunicationDebugForm);
#else
            gsmModem = new GsmModem(Com);
#endif

            ComIndex = index;
            gsmModem.dIP[0] = 10;
            gsmModem.dIP[1] = 0;
            gsmModem.dIP[2] = 0;
            gsmModem.dIP[3] = 172;
            gsmModem.dPort = 80;       
            gsmModem.AddLog += new strEventHandler(gsmModem_AddLog);
            
        }

        void gsmModem_AddLog(object sender, strEventArgs e)
        {
            OnAddLog(e.strArg);
        }
        public void ReaderThreadStart()
        {
            ReaderThreadIns = new Thread(new ThreadStart(ReaderProc));
            ReaderThreadIns.Name = "签到" + Com.PortName;
            PortName = Com.PortName;
            ReaderThreadIns.Start();
            OnAddLog("签到开始");
        }
        private void ReaderProc()
        {
             //try
             {
                while (true)
                {
                    try
                    {
                        Com.Open();
                        //Com.RtsEnable = true;
                    }
                    catch
                    {
                        OnAddLog("串口无法打开,请终止软件");
                        OnFinishEvent((int)FinishType.Unkown);
                        break;
                    }
                    OnAddLog("开始初始化");
                    if (!gsmModem.InitGSMModem())
                    {
                        break;
                    }
                    OnAddLog("初始化成功");
                    OnAddLog("开始拨号");
                    if (!gsmModem.InitPPPConnect())
                    {
                        break;
                    }
                    OnAddLog("拨号成功");
                    string uri;
                    string tx;
                    object o;
                    string str="";
                    string signCode = "";
                    //string signCodeSystem = "";
                    string themeid = "";
                    string signInId = "";
                    string ptype = "";
                    string fpid = "";
                    string pid = "";
                    string sid = "";
                    Http http=null;
                    WebHeaderCollection httpHeader = new WebHeaderCollection();
                    httpHeader[HttpRequestHeader.UserAgent] = "NokiaN82/1.0 (20.1.062) SymbianOS/9.2 Series60/3.1 Profile/MIDP-2.0 Configuration/CLDC-1.1";
                    httpHeader[HttpRequestHeader.Accept] = "text/html";
                    httpHeader[HttpRequestHeader.AcceptEncoding] = "utf-8";
                    httpHeader[HttpRequestHeader.AcceptLanguage] = "zh-CN, en-US";
                    CookieCollection cookies = new CookieCollection();                     
                    bool bok = false;
                    while (true)
                    {
                        uri = "http://go.10086.cn/";
                        httpHeader[HttpRequestHeader.Accept] = "text/html";
                        httpHeader[HttpRequestHeader.AcceptEncoding] = "utf-8";
                        tx = HttpStatic.HttpHeaderToStr(uri, httpHeader, cookies);
                        if (!gsmModem.TCPRead(new List<byte>(Encoding.ASCII.GetBytes(tx))))
                        {
                            OnAddLog("获得tcp数据失败!");
                            OnFinishEvent((int)FinishType.Unkown);
                            break;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            break;
                        http = (Http)o;
                        if (http.ContentDatas.Count == 0)
                            break;
                        str = HttpStatic.ContentToStr(http);
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);
                        int x = str.IndexOf("onevent type=\"onenterforward\"");
                        if (x != -1)
                        {
                            x = str.IndexOf("go href=\"", x);
                            if (x != -1)
                            {
                                x += 9;
                                OnAddLog("获得跳转页");
                                httpHeader[HttpRequestHeader.Referer] = uri;
                                uri = WFNetLib.Strings.StringsFunction.strDecode(str.Substring(x, str.IndexOf('\"', x) - x));
                                if (http.Cookies.Count != 0)
                                {
                                    foreach (Cookie c in http.Cookies)
                                    {
                                        if (cookies[c.Name] != null)
                                            cookies[c.Name].Value = c.Value;
                                        else
                                            cookies.Add(c);
                                    }
                                }
                                httpHeader[HttpRequestHeader.Accept] = "text/html";
                                httpHeader[HttpRequestHeader.AcceptEncoding] = "utf-8";
                                tx = HttpStatic.HttpHeaderToStr(uri, httpHeader, cookies);
                                if (!gsmModem.TCPRead(new List<byte>(Encoding.ASCII.GetBytes(tx))))
                                {
                                    OnAddLog("获得tcp数据失败!");
                                    OnFinishEvent((int)FinishType.Unkown);
                                    break;
                                }
                                o = gsmModem.TCPData.oTCPDatas;
                            }
                        }
                        if (o == null)
                            break;
                        http = (Http)o;
                        OnAddLog("获得签到页");
                        str = HttpStatic.ContentToStr(http);//signCode=2984&signCodeSystem=298&themeid=18284&signInId=371&ptype=22&fpid=408035&pid=408030
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        CommunicationDebugForm.ExternShowRx(str);                        
                        x = str.IndexOf("name=\"themeid\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"themeid\" value=\"".Length;
                        themeid = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("name=\"signInId\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"signInId\" value=\"".Length;
                        signInId = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("name=\"ptype\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"ptype\" value=\"".Length;
                        ptype = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("name=\"fpid\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"fpid\" value=\"".Length;
                        fpid = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("name=\"pid\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"pid\" value=\"".Length;
                        pid = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("name=\"sid\" value=\"");
                        if (x == -1)
                            break;
                        x += "name=\"sid\" value=\"".Length;
                        sid = str.Substring(x, str.IndexOf('\"', x) - x);

                        x = str.IndexOf("img src=\"Kaptcha.jpg?ran=");
                        if (x == -1)
                            break;
                        x = x + "img src=\"Kaptcha.jpg?ran=".Length;

                        uri = str.Substring(x, str.IndexOf('\"', x) - x);
                        string ran = uri;
                        Debug.WriteLine(uri);
                        uri = "http://go.10086.cn/g/Kaptcha.jpg?ran=" + uri;
                        if (http.Cookies.Count != 0)
                        {
                            foreach (Cookie c in http.Cookies)
                            {
                                if (cookies[c.Name] != null)
                                    cookies[c.Name].Value = c.Value;
                                else
                                    cookies.Add(c);
                            }
                        }
                        OnAddLog("获得签到图片");
                        httpHeader[HttpRequestHeader.Accept] = "image/jpeg";
                        tx = HttpStatic.HttpHeaderToStr(uri, httpHeader, cookies);
                        if (!gsmModem.TCPRead(new List<byte>(Encoding.ASCII.GetBytes(tx))))
                        {
                            OnAddLog("获得tcp数据失败!");
                            OnFinishEvent((int)FinishType.Unkown);
                            break;
                        }
                        o = gsmModem.TCPData.oTCPDatas;
                        if (o == null)
                            break;
                        http = (Http)o;
                        string file = "";
                        CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                        if (http.ContentDatas.Count != 0)
                        {
                            if (http.httpHeader[HttpResponseHeader.ContentType].IndexOf("image") != -1)
                            {
                                string ext = http.httpHeader[HttpResponseHeader.ContentType].Split('/')[1];
                                file = System.Windows.Forms.Application.StartupPath + "\\gif\\" + ReaderThreadIns.Name + "." + ext;
                                FileInfo f = new FileInfo(file);
                                if (!Directory.Exists(f.DirectoryName))
                                    Directory.CreateDirectory(f.DirectoryName);
                                FileStream fs = new FileStream(file, FileMode.Create);
                                BinaryWriter bw = new BinaryWriter(fs);
                                bw.Write(http.ContentDatas.ToArray());
                                //清空缓冲区
                                bw.Flush();
                                //关闭流
                                bw.Close();
                                fs.Close();/**/

                            }
                        }
                        else
                            break;
                        Form2 f1 = new Form2();
                        f1.Text = ReaderThreadIns.Name + "验证码";
                        f1.file = file;
                        if (f1.ShowDialog() == DialogResult.OK)
                        {
                            signCode = f1.signCode;
                            bok = true;
                            break;
                        }
                        OnAddLog("重新获得签到数据");
                    }
                    if(!bok)
                        break;
                    uri = "http://go.10086.cn/g/signInCode.do";
                    if (http.Cookies.Count != 0)
                    {
                        foreach (Cookie c in http.Cookies)
                        {
                            if (cookies[c.Name] != null)
                                cookies[c.Name].Value = c.Value;
                            else
                                cookies.Add(c);
                        }
                    }
                    //signCode=2984&signCodeSystem=298&themeid=18284&signInId=371&ptype=22&fpid=408035&pid=408030                    
                    string post = "signCode=" + signCode + "&";
                    post = post + "themeid=" + themeid + "&";
                    post = post + "signInId=" + signInId + "&";
                    post = post + "ptype=" + ptype + "&";
                    post = post + "fpid=" + fpid + "&";
                    post = post + "pid=" + pid + "&";
                    post = post + "sid=" + sid;
                    Debug.WriteLine(post);
                    httpHeader[HttpRequestHeader.ContentLength] = post.Length.ToString();
                    httpHeader[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                    httpHeader[HttpRequestHeader.Accept] = "text/html";
                    tx = HttpStatic.HttpHeaderToStr("POST", uri, httpHeader, cookies);
                    tx = tx + post;
                    Debug.WriteLine(tx);
                    OnAddLog("进行签到");
                    //                     if (gsmModem.strATI == "HUAWEIGTM900")
                    //                     {
                    //                         o = gsmModem.GTM900_TCPIPRead(tx);
                    //                     }
                    //                     else
                    //                     {
                    if (!gsmModem.TCPRead(new List<byte>(Encoding.ASCII.GetBytes(tx))))
                    {
                        OnAddLog("获得tcp数据失败!");
                        OnFinishEvent((int)FinishType.Unkown);
                        break;
                    }

                    o = gsmModem.TCPData.oTCPDatas;
                    /*}*/
                    if (o == null)
                        break;
                    http = (Http)o;
                    str = HttpStatic.ContentToStr(http);
                    CommunicationDebugForm.ExternShowRx(http.strHttpHeader);
                    CommunicationDebugForm.ExternShowRx(str);
                    
                    OnAddLog("关闭连接");

//                     if (gsmModem.strATI == "HUAWEIGTM900")
//                     {
//                         gsmModem.GTM900_CloseTCPIP();
//                     }
//                     else
//                     {
                        if (!gsmModem.pppClose())
                        {
                            OnAddLog("ppp关闭失败");
                        }
                        else
                        {
                            OnAddLog("ppp关闭成功");
                        }
                   /* }*/
                    if (str.IndexOf("签到成功") != -1)
                    {
                        OnAddLog("签到成功");
                        OnFinishEvent((int)FinishType.Finish);
                    }
                    else if (str.IndexOf("签到失败（一天只允许签到一次）") != -1)
                    {
                        OnAddLog("签到失败（一天只允许签到一次）");
                        OnFinishEvent((int)FinishType.DoAgain);
                    }
                    else
                    {
                        OnAddLog("未知签到结果");
                        OnFinishEvent((int)FinishType.Unkown);
                    }
                    Com.Close();
                    return;
                }
                if (!gsmModem.pppClose())
                {
                    OnAddLog("ppp关闭失败");
                }
                else
                {
                    OnAddLog("ppp关闭成功");
                }
                OnAddLog("<未知退出>");
                OnFinishEvent((int)FinishType.Unkown);
                Com.Close();
             }
//              catch (System.Exception ex)
//              {
//                  if (!gsmModem.pppClose())
//                  {
//                      OnAddLog("ppp关闭失败");
//                  }
//                  else
//                  {
//                      OnAddLog("ppp关闭成功");
//                  }
//                  OnAddLog("<未知退出>" + ex.Message);
//                  OnFinishEvent((int)FinishType.Unkown);
//                  Com.Close();
//              }            
        }        
    }
    public enum FinishType
    {
        Finish=0,
        DoAgain=1,
        Unkown=2
    }
}
